#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <sys/shm.h>

const std::string name = "/home/fang/tab7"; // 项目路径
int pro = 0x6666;                           // 随便数字
mode_t mode = 0660;
std::string x_16(key_t k)
{
    char buff[1024];
    snprintf(buff, sizeof(buff), "0x%x", k);
    return buff;
}

struct data
{
    char status[32];//数据状态
    char lasttime[48];//消息最新被修改时间
    char imge[1024];//发送图片大小
};

class commshm
{
private:
    void Shmget(int ipc)
    {
        k = ::ftok(name.c_str(), pro);
        if (k < 0)
        {
            std::cout << "创建key失败" << std::endl;
            return;
        }

        // 创建共享内存
        shmid = ::shmget(k, 4096, ipc);
        std::cout << "shmid:" << shmid << std::endl;
        if (shmid < 0)
        {
            std::cout << "创建共享内存失败" << std::endl;
            return;
        }
        std::cout << "更新内存创建成功" << std::endl;
    }

public:
    commshm() : shmid(-1)
    {
    }
    void test1()
    {
        if (shmid == -1)
        {
            Shmget(IPC_CREAT | IPC_EXCL | mode);
        }
    }

    void test2()
    {
        Shmget(IPC_CREAT);
    }

    void Shmat()
    {
        // 挂接到自己的虚拟地址空间
        ret = ::shmat(shmid, nullptr, 0);
        if ((long long)ret == -1)
        {
            std::cout << "挂接失败" << std::endl;
            exit(1);
        }
        std::cout << "挂接成功" << std::endl;
    }

    void Shmdt()
    {
        // 去关联
        shmdt(ret);
        std::cout << "去关联成功" << std::endl;
    }
    void SHmctl()
    {
        // 删除共享内存
        shmctl(shmid, IPC_RMID, nullptr);
        std::cout << "删除共享内存" << std::endl;
    }
    // 返回虚拟地址空间的地址
    void *Ret()
    {
        return ret;
    }
    void shmmete() // 显示共享内存的信息
    {
        struct shmid_ds add;//系统
        int n = ::shmctl(shmid,IPC_STAT,&add);
        if(n < 0) 
        {
            std::cout << "错误" << std::endl;
            return ;
        }
        std::cout << "####################" << std::endl;
        std::cout << add.shm_atime << std::endl;
        std::cout << add.shm_cpid << std::endl;
        std::cout << add.shm_ctime << std::endl;
        std::cout << add.shm_dtime << std::endl;
        std::cout << add.shm_lpid << std::endl;
        std::cout << "####################" << std::endl;

    }

private:
    key_t k;
    int shmid;
    void *ret;
};

commshm s;